iT邦幫忙

2026 iThome 鐵人賽

DAY 3
0
AI 自動化

從 BPM 到 Agentic Workflow:企業 AI 流程的狀態、控制與驗證系列 第 3

Day 03|哪些事交給 LLM,哪些事不要

  • 分享至 

  • xImage
  •  

昨天我把「企業共享資源協調」做成一套與我的工作無關、可以公開的 Reference System。成功路徑已經能從 NEW 走到 SUCCEEDED,也真的在 SQLite 留下一筆 booking。

但我回頭看整條 trace 時,發現最值得在意的不是「Agent 會不會找會議室」,而是這個問題:

如果模型說「可以預約」,誰來確定真的可以?

這就是今天要拆的邊界。


我先不用「智慧」和「規則」來分

一開始我也很容易把任務分成「聯明的事交給 LLM,其他交給程式」。但這種分法太模糊。模型能做出一個看起來合理的判斷,不代表適合成為最後的決定者。

我改用一個更實際的問法:這個步驟如果判斷錯誤,能不能只是重新算一次?還是已經會改變權限、金錢或系統狀態?

依這個標準,我把流程分成五段:

階段 共享資源範例 LLM 的位置 最後決定者
Understand 「明天下午晚一點」是什麼時段 解釋、抽取、標記不確定 Typed schema
Propose 哪些資源符合人數與設備 排候選、產生說明 查詢結果與硬性過濾
Authorize 這個人可不可以用受限資源 可解釋原因,不可自行放行 RBAC、policy、人工核准
Commit 真正寫入預約 不持有資料庫權限 Typed tool 與 transaction
Recover 寫入後的下游步驟失敗 可協助分類錯誤 retry、compensation、workflow state

這張表改變了我對 Agent 的想像。LLM 不是從輸入一路接管到寫入資料庫;比較像在可控流程裡,專門處理模糊資訊的一個組件。

LLM 可以提案,但提案不是指令

假設使用者說:

幫我找明天下午晚一點、十個人、要有投影機的空間。

模型可以轉成候選的 structured intent,但我不會讓這個 JSON 直接進 tool。在 Reference System 裡,這個物件還要通過確定性檢查:

proposal = llm_extract(user_message)  # 只是提案

intent = service.validate_typed_intent(proposal)
run = service.start_booking_workflow(
    actor_id="alice",  # synthetic fixture 中的使用者
    intent_payload=intent.to_dict(),
    idempotency_key=request_id,
    raw_request=user_message,
)

validate_typed_intent() 會檢查 action、resource type、timezone、duration 與 capacity;start_booking_workflow() 才會進入狀態機、policy 與 RBAC。即使模型產生了 action: create_booking,也不等於已獲得執行權。

我特別在意這個名稱:proposal。如果一開始就把模型輸出叫做 command,後面的程式很容易不知不覺把當成已核准的指令。

我刻意測了三條不應該交給 LLM 的邊界

這一天沒有連接外部模型或真實系統。我用暫存 SQLite 與 synthetic identities 重跑現有的 integration tests,因為我想驗證的是「模型外面的邊界有沒有站住」。

1. Typed contract 不接受模糊時間

第一個 test 先送進沒有 timezone 的時間,再送進 17 分鐘的 duration。兩者都必須在 tool call 前被拒絕;合法輸入則會正規化為 UTC。

test_typed_intent_requires_explicit_timezone_and_valid_contract ... ok

我從這裡觀察到,「明天下午」可以讓模型解釋,但時區尚未確認時,系統應該停下來追問,而不是自行猜一個時區後寫入。

2. 需要核准的動作,不能用一句話跳過

第二個 test 用 180 分鐘預約觸發人工核准。我先直接呼叫 booking tool,系統拒絕;接著讓 workflow 通過申請人確認與管理者核准,才能進入 SUCCEEDED

test_confirmation_approval_state_audit_and_trace_are_persisted ... ok

我看到的重點不是 test 變綠色,而是中間狀態真的被持久化。服務重新建立後,仍然讀得到 AWAIT_CONFIRMATION,不需要由模型根據對話重新推測。

3. Prompt 不能覆寫 RBAC

第三個 test 先讓一個 synthetic user 嘗試取消別人的預約,再把「bypass RBAC」類型的文字放進 raw request。兩條路徑都被拒絕,原本預約仍是 active,且 audit log 多了一筆 denied security event。

test_rbac_and_prompt_injection_tool_abuse_are_denied ... ok

這裡的邏輯很直接:不管使用者怎麼說,權限來自 actor identity 與 policy,不是來自 prompt 的說服力。

三個 test 通過,不等於這套系統已安全

這次結果只證明三件事:輸入 contract 會擋下已知的非法形狀;核准狀態不能被 tool call 繞過;已寫入的 RBAC 與一組惡意文字樣本能被拒絕。

沒有證明:

  • 模型永遠能正確抽取 intent。
  • 關鍵字檢查可以阻擋所有 prompt injection。
  • policy 沒有邏輯漏洞。
  • 系統已處理併發、重試與下游失敗。

後面這些會各自有專門的實驗。我不想因為今天有三行 ok,就把結論寫成「Agentic Workflow 已通過安全驗證」。

我現在怎麼判斷要不要交給 LLM

我最後留下五個問題。只要其中一題的答案是「是」,我就不讓 LLM 單獨做最後決定:

  1. 這個步驟會不會產生不容易撤銷的 side effect?
  2. 是否涉及身份、權限、金額、配額或法規?
  3. 兩次執行會不會產生兩份結果?
  4. 多人同時操作時,是否需要一致性?
  5. 失敗後是否需要明確的回復與審計路徑?

對這些問題,LLM 仍然可以提供摘要、解釋與候選方案;只是最後那條不可越過的邊界,必須寫在模型之外。

今天的結論

我原本以為 Agentic Workflow 的關鍵是讓模型知道「下一步要做什麼」。真的把流程跑過一次後,我反而認為更重要的是:

LLM 用來處理模糊性;系統用來限定可以發生什麼,並證明最後真的發生了什麼。

明天我會把這些責任擺回一張完整架構裡,分清 Conversation、Orchestrator、Tool、Policy 與 State 之間的關係。

下一篇:Day 04|Agentic Workflow 參考架構:Conversation、Orchestrator、Tool、Policy、State


操作交接

要在另一個環境重跑這三條邊界測試,請使用 docs/day03-operations/04-ai-automation-control-boundary.md。實驗只使用 synthetic identities 與暫存 SQLite,不需要雲端資源或真實公司系統。

參考資料

  1. Anthropic, Building Effective Agents
  2. Python Documentation, sqlite3 — Transaction control
  3. OMG, Business Process Model and Notation 2.0.2

本篇的使用者、資源、時間與規則均為 synthetic data,與我手上的CASE無關。


上一篇
Day 02|Reference System:用「企業共享資源協調」取代真實公司系統
下一篇
Day 04|Agentic Workflow 參考架構:Conversation、Orchestrator、Tool、Policy、State
系列文
從 BPM 到 Agentic Workflow:企業 AI 流程的狀態、控制與驗證10
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言